/*
 * Copyright 2020 The Context Mapper Project Team
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.contextmapper.dsl.ide.tests.commands.refactoring

import com.google.gson.JsonArray
import com.google.gson.JsonPrimitive
import org.contextmapper.dsl.ide.commands.CMLCommandService
import org.contextmapper.dsl.ide.tests.commands.AbstractCMLCommandTest
import org.eclipse.lsp4j.ExecuteCommandParams
import org.junit.jupiter.api.Test
import static org.junit.jupiter.api.Assertions.assertTrue

class ExtractSuggestedServiceCommandTest extends AbstractCMLCommandTest {

	@Test
	def void testARCommandExecution() {
		// given
		initializeCommandsDynamically()
		val originalModel = '''
			BoundedContext TestContext {
				Aggregate TestAggregate1 {
					Entity Customer {
						String firstName
						String lastName
					}
					Entity Address {
						String street
						String city
					}
				}
			}
		'''
		val serviceCutSuggestion = '''
			BoundedContext Service_A {
				Aggregate Service_A_Aggregate_1 {
					Entity Customer {
						String firstName
						String lastName
					}
				}
			}
			BoundedContext Service_B {
				Aggregate Service_B_Aggregate_1 {
					Entity Address {
						String street
						String city
					}
				}
			}
			
		'''
		val originalFileURI = 'test.cml'.writeFile(originalModel)
		val serviceCutFileURI = 'test_Markov_Clustering_Cut_1.cml'.writeFile(serviceCutSuggestion)

		// when
		val refactoringParams = new JsonArray
		refactoringParams.add(serviceCutFileURI.toString)
		refactoringParams.add("Service_A")
		refactoringParams.add("CustomerContext")

		val result = languageServer.executeCommand(
			new ExecuteCommandParams("cml.ar.extractSuggestedService",
				#[new JsonPrimitive(originalFileURI), refactoringParams]))
		val resultVal = result.get as String

		// then
		CMLCommandService.COMMAND_EXECUTED_RETURN_VALUE.assertEquals(resultVal)
	}

	@Test
	def void canThrowExceptionIfServiceCutModelDoesNotExist() {
		// given
		initializeCommandsDynamically()
		val originalModel = '''
			BoundedContext TestContext {
				Aggregate TestAggregate1 {
					Entity Customer {
						String firstName
						String lastName
					}
					Entity Address {
						String street
						String city
					}
				}
			}
		'''
		val originalFileURI = 'test.cml'.writeFile(originalModel)
		val serviceCutFileURI = 'test_Markov_Clustering_Cut_1.cml'.writeFile("")

		// when
		val refactoringParams = new JsonArray
		refactoringParams.add(serviceCutFileURI.toString)
		refactoringParams.add("Service_A")
		refactoringParams.add("CustomerContext")

		val result = languageServer.executeCommand(
			new ExecuteCommandParams("cml.ar.extractSuggestedService",
				#[new JsonPrimitive(originalFileURI), refactoringParams]))
		val resultVal = result.get as String

		// then
		assertTrue(resultVal.startsWith(CMLCommandService.COMMAND_EXECUTION_ERROR_PREFIX))
	}

	@Test
	def void canThrowExceptionIfServiceCutBCDoesNotExist() {
		// given
		initializeCommandsDynamically()
		val originalModel = '''
			BoundedContext TestContext {
				Aggregate TestAggregate1 {
					Entity Customer {
						String firstName
						String lastName
					}
					Entity Address {
						String street
						String city
					}
				}
			}
		'''
		val serviceCutSuggestion = '''
			BoundedContext Service_B {
				Aggregate Service_B_Aggregate_1 {
					Entity Address {
						String street
						String city
					}
				}
			}
			
		'''
		val originalFileURI = 'test.cml'.writeFile(originalModel)
		val serviceCutFileURI = 'test_Markov_Clustering_Cut_1.cml'.writeFile(serviceCutSuggestion)

		// when
		val refactoringParams = new JsonArray
		refactoringParams.add(serviceCutFileURI.toString)
		refactoringParams.add("Service_A")
		refactoringParams.add("CustomerContext")

		val result = languageServer.executeCommand(
			new ExecuteCommandParams("cml.ar.extractSuggestedService",
				#[new JsonPrimitive(originalFileURI), refactoringParams]))
		val resultVal = result.get as String

		// then
		assertTrue(resultVal.startsWith(CMLCommandService.COMMAND_EXECUTION_ERROR_PREFIX))
	}

}
